package com.rssreader.client.grids;

import java.util.ArrayList;
import java.util.List;

import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.core.XTemplate;
import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.ListLoadResult;
import com.extjs.gxt.ui.client.data.ListLoader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.dnd.GridDragSource;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.mvc.Dispatcher;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.extjs.gxt.ui.client.widget.grid.RowExpander;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.rssreader.client.RSSReaderConstants;
import com.rssreader.client.mvc.events.AppEvents;
import com.rssreader.client.services.FeedServiceAsync;
import com.rssreader.shared.model.Feed;
import com.rssreader.shared.model.Item;

public class ItemGrid extends LayoutContainer {
    private final Feed feed;
    private Grid<ModelData> grid;

    public ItemGrid(Feed feed) {
	setLayout(new FitLayout());
	this.feed = feed;
    }

    @Override
    protected void onRender(Element parent, int index) {
	super.onRender(parent, index);
	// ColumnConfig可以有很多組，存入list裡，然後傳到ColumnModel的建構式中，生成實體物件
	final List<ColumnConfig> columns = new ArrayList<ColumnConfig>();
	// columns.add(new ColumnConfig("title", "Title", 200));
	// columns.add(new ColumnConfig("description", "Description", 200));
	// columns.add(new ColumnConfig("link", "Link", 200));

	GridCellRenderer<ModelData> itemsRenderer = new GridCellRenderer<ModelData>() {
	    @Override
	    public String render(ModelData model, String property,
		    ColumnData config, int rowIndex, int colIndex,
		    ListStore<ModelData> store, Grid<ModelData> grid) {

		// retrieves the title, description, and link fields from the
		// model
		// and combines them in an HTML string
		String title = model.get("title");
		String description = model.get("description");
		String link = model.get("link");
		return "<b>" + title + "</b><br/>" + description + "<br/>" + link;
	    }
	};

	// create a new ColumnConfig with the ID of items, and set the renderer
	// to be the itemsRenderere
	ColumnConfig column = new ColumnConfig();
	column.setId("items");
	column.setRenderer(itemsRenderer);
	column.setHeader("Items");
	// add the items column to the list of columns
	columns.add(column);

	XTemplate xTemplate = XTemplate
		.create("<img class=\"left\" src=\"{thumbnailUrl}\" height=\"49px\"/>"
			+ "<p>{description}, {pubDate}</p>");
	RowExpander rowExpander = new RowExpander();
	rowExpander.setTemplate(xTemplate);

	columns.add(rowExpander);

	// 將定義好的columns傳入ColumnModel的建構式中
	final ColumnModel columnModel = new ColumnModel(columns);
	// example RSS URL
	// final String TEST_DATA_FILE = "http://feeds.feedburner.com/extblog";
	final FeedServiceAsync feedService = Registry
		.get(RSSReaderConstants.FEED_SERVICE);

	// create an RpcProxy去掉用FeedService的loadItems方法
	RpcProxy<List<Item>> proxy = new RpcProxy<List<Item>>() {
	    @Override
	    protected void load(Object loadConfig, AsyncCallback<List<Item>> callback) {
		feedService.loadItems(feed.getUuid(), callback);
	    }
	};

	// 因為Item是繼承BaseModel（其屬性都是用get／set寫成的）來實現modelData
	// 故reader不需要create a BaseListLoader，可以直接通過RpcProxy獲得
	ListLoader<ListLoadResult<Item>> loader = new BaseListLoader<ListLoadResult<Item>>(
		proxy);
	// 透過loader，獲得store數據
	ListStore<ModelData> itemStore = new ListStore<ModelData>(loader);

	// create a grid using the Store and the ColumnModel
	grid = new Grid<ModelData>(itemStore, columnModel);
	grid.setBorders(true);
	grid.setAutoExpandColumn("items");
	// grid.setAutoExpandColumn("description"); // the description column
	// expands to fill the available space

	// add the RowExpander to the Grid as a plugin
	grid.addPlugin(rowExpander);

	// 當user選擇不同的item時，就會觸發selectionChange事件，將傳入的selectedItem派發出去
	grid.getSelectionModel().addListener(Events.SelectionChange,
		new Listener<SelectionChangedEvent<Item>>() {

		    @Override
		    public void handleEvent(SelectionChangedEvent<Item> be) {
			Item item = be.getSelectedItem();
			if (item != null) {
			    Dispatcher.forwardEvent(AppEvents.ItemSelected, item);
			}
		    }
		});

	// call the load method of the ListLoader to load the Item objects into
	// the Store of the Grid
	loader.load();

	GridDragSource source = new GridDragSource(grid);
	source.setGroup(RSSReaderConstants.ITEM_DD_GROUP);

	add(grid);
    }

    public void resetSelection() {
	grid.getSelectionModel().deselectAll();
    }
}
